#!/usr/bin/env python3
"""
邮件发送工具函数
"""
import smtplib
import os
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.mime.application import MIMEApplication
from typing import Optional, Dict


def send_email_with_attachment(
    smtp_server: str,
    smtp_port: int,
    smtp_username: str,
    smtp_password: str,
    from_email: str,
    to_email: str,
    subject: str,
    body: str,
    attachment_path: str,
    use_tls: bool = True,
) -> tuple[bool, str]:
    """
    发送带附件的邮件
    
    Args:
        smtp_server: SMTP服务器地址
        smtp_port: SMTP服务器端口
        smtp_username: SMTP用户名
        smtp_password: SMTP密码
        from_email: 发件人邮箱
        to_email: 收件人邮箱
        subject: 邮件主题
        body: 邮件正文
        attachment_path: 附件文件路径
        use_tls: 是否使用TLS加密（端口587时使用）
    
    Returns:
        tuple[bool, str]: (成功状态, 消息)
    """
    try:
        # 验证附件文件是否存在
        if not os.path.exists(attachment_path):
            return False, f"附件文件不存在: {attachment_path}"
        
        # 创建邮件对象
        msg = MIMEMultipart()
        msg['From'] = from_email
        msg['To'] = to_email
        msg['Subject'] = subject
        
        # 添加邮件正文
        msg.attach(MIMEText(body, 'plain', 'utf-8'))
        
        # 添加附件
        with open(attachment_path, 'rb') as f:
            part = MIMEApplication(f.read())
            part.add_header('Content-Disposition', 'attachment', filename=os.path.basename(attachment_path))
            msg.attach(part)
        
        # 根据端口选择连接方式
        if smtp_port == 465:
            # 端口465使用SSL连接
            server = smtplib.SMTP_SSL(smtp_server, smtp_port)
            server.set_debuglevel(0)  # 关闭调试信息
        else:
            # 其他端口（如587）使用常规SMTP连接
            server = smtplib.SMTP(smtp_server, smtp_port)
            server.set_debuglevel(0)  # 关闭调试信息
            
            # 使用TLS加密
            if use_tls:
                server.starttls()
        
        # 登录SMTP服务器
        server.login(smtp_username, smtp_password)
        
        # 发送邮件
        server.send_message(msg)
        
        # 关闭连接
        server.quit()
        
        return True, f"邮件发送成功，附件: {os.path.basename(attachment_path)}"
        
    except smtplib.SMTPAuthenticationError:
        return False, "SMTP认证失败，请检查用户名和密码"
    except smtplib.SMTPConnectError:
        return False, f"无法连接到SMTP服务器: {smtp_server}:{smtp_port}"
    except smtplib.SMTPException as e:
        return False, f"SMTP错误: {str(e)}"
    except Exception as e:
        return False, f"发送邮件失败: {str(e)}"


def send_database_backup_email(config: Dict, backup_file_path: str) -> tuple[bool, str]:
    """
    发送数据库备份邮件
    
    Args:
        config: 包含邮件配置的字典
        backup_file_path: 备份文件路径
    
    Returns:
        tuple[bool, str]: (成功状态, 消息)
    """
    # 从配置中提取邮件相关信息
    email_config = config.get('email', {})
    backup_config = config.get('backup', {})
    
    # 验证必要的配置项
    required_fields = ['smtp_server', 'smtp_port', 'smtp_username', 'smtp_password', 'from_email']
    for field in required_fields:
        if not email_config.get(field):
            return False, f"邮件配置不完整，缺少必要字段: {field}"
    
    # 验证备份配置中的收件人邮箱
    to_email = backup_config.get('to_email')
    if not to_email:
        return False, "备份配置不完整，缺少必要字段: to_email"
    
    # 发送邮件
    subject = f"数据库备份 - {os.path.basename(backup_file_path)}"
    body = f"这是自动生成的数据库备份邮件。\n\n备份文件名: {os.path.basename(backup_file_path)}\n\n备份时间: {os.path.basename(backup_file_path).split('_')[-2]}\n\n网站地址：{config.get('website', {}).get('url', 'https://guzian.cn:810')}\n\n请妥善保管备份文件，避免丢失导致数据丢失。"
    
    return send_email_with_attachment(
        smtp_server=email_config['smtp_server'],
        smtp_port=int(email_config['smtp_port']),
        smtp_username=email_config['smtp_username'],
        smtp_password=email_config['smtp_password'],
        from_email=email_config['from_email'],
        to_email=to_email,
        subject=subject,
        body=body,
        attachment_path=backup_file_path,
        use_tls=email_config.get('use_tls', True),
    )